package com.xiaojie.importdata.handler.impl;

import cn.hutool.core.map.MapUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.xiaojie.context.DataInfoContext;
import com.xiaojie.importdata.handler.AbstractReplaceFieldValueHandler;
import com.xiaojie.parse.model.DataModel;
import com.xiaojie.parse.model.Table;
import com.xiaojie.toolkits.FieldNameUtil;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 根据传入的参数替换字段值
 *
 * @ClassName ReplaceFieldValueByParams
 * @Author wangye
 * @Date 2022/3/13
 **/
public class ReplaceFieldValueByParams extends AbstractReplaceFieldValueHandler {


    /**
     * 根据传入的参数值替换字段值，自定义配置优于全局配置
     *
     * @param tableName
     * @param table
     * @param rowData
     * @Author: wangye
     * @Date: 2022/3/13 11:13
     * @return:
     **/
    @Override
    public void replaceFieldValue(String tableName, Table table, Map rowData) {

        if (table.getSettings() == null || MapUtil.isEmpty(table.getSettings().getReplaceFields())) {
            return;
        }

        Map<String, Object> newFieldValueParams = DataInfoContext.get().getNewFieldValueParams();

        DataModel dataModel = DataInfoContext.get().getDataModelInfo();

        Map<String, Map<String, Map>> refFieldDataMap = DataInfoContext.get().getRefFieldValueMap();

        Map<String, Set<String>> refFieldsMap = dataModel.getRefFieldsMap();

//        Settings globalSettings = dataModel.getSettings();
//
//        //合并全局配置和表级配置,相同字段表级优先级高
//        Map<String, String> replaceFields = Maps.newHashMap();
//        if (globalSettings != null && globalSettings.getReplaceFields() != null) {
//            replaceFields.putAll(globalSettings.getReplaceFields());
//        }
//        if (table.getSettings() != null && table.getSettings().getReplaceFields() != null) {
//            replaceFields.putAll(table.getSettings().getReplaceFields());
//        }

        //获取存储新旧数据容器
        Map<String, Map> tableCorrespondFieldsMap = Optional.ofNullable(
                DataInfoContext.get().getCorrespondDataTableFieldMap().get(tableName)).orElse(Maps.newHashMap());
        //获取表中需要保留新旧数据关系的字段名
//        List<String> correspondDataFieldNames = getCorrespondFieldNames(table.getSettings(), globalSettings);
        List<String> correspondDataFieldNames = Optional.ofNullable(table.getSettings()).flatMap(s -> Optional.ofNullable(s.getCorrespondDataFields()))
                .orElse(Lists.newArrayList())
                .stream().map(fieldName -> FieldNameUtil.convert(fieldName)).collect(Collectors.toList());

        Map<String, String> replaceFieldsMap = Optional.ofNullable(table.getSettings())
                .flatMap(settings -> Optional.ofNullable(settings.getReplaceFields()))
                .orElse(Maps.newHashMap());
        replaceFieldsMap.entrySet().forEach(fieldEntry -> {
            // 获取要被替换的字段名
            String fieldName = FieldNameUtil.convert(fieldEntry.getKey());
            //替换值 参数名
            String paramName = fieldEntry.getValue();
            Map correspondFieldMap = Optional.ofNullable(tableCorrespondFieldsMap.get(fieldName)).orElse(Maps.newHashMap());
            //数据库数据包含 替换字段名
            //1.替换数据
            if (rowData.containsKey(fieldName)) {
                Object oldV = rowData.get(fieldName);
                Object newV = getReplaceNewValue(newFieldValueParams, paramName, oldV);
                if (newV != null) {
                    rowData.put(fieldName, newV);
                    correspondFieldMap.put(oldV, newV);
                    buildFieldRefDataMap(refFieldDataMap, tableName, oldV, refFieldsMap, fieldName, newV);
                }
            }

            //2.将在替换字段里 把数据放入 上下文 的 「新旧对照关系」
            //保存新旧数对应关系
            if (correspondDataFieldNames.contains(fieldName)) {
                tableCorrespondFieldsMap.put(fieldName, correspondFieldMap);
            }
        });
        //将新旧数据对应关系保存在上下文中
        DataInfoContext.get().getCorrespondDataTableFieldMap().put(tableName, tableCorrespondFieldsMap);
    }


    /**
     * @param param     导出参数map
     * @param paramName 被替换字段名
     * @return
     */
    private Object getReplaceNewValue(Map<String, Object> param, String paramName, Object oldValue) {
        Object newValue = param.get(paramName);
        if (newValue instanceof Map) {
            //如果传入的参数是map
            Map map = (Map) newValue;
            newValue = map.get(oldValue);
        }
        return newValue;
    }
}
